<template lang="pug">
Dialog.screen-sync(title='多屏互动' :show.sync='show' round :fullscreen='false' :height='isPc ? "500px" : "120vw"' :width='isPc ? "900px" : ""')

  van-tabs.flex-1.ff-cn(v-model="active"  style='' animated)

    van-tab(:title="!connectInfo.room_id ? '创建房间' : '房间信息'")
      .ff-cn.jc-between.h100p.ai-center
        .top(v-if="getUserInfoData")
          p.fs-n 点击创建房间后，请在另外的设备上，输入下方房间号( 小程序用户可直接转发给其他用户 )，加入房间互动
          van-field.bd-b.bd-t.mgt2(label='场景ID(固定分配)' label-width='140px' :value="this.$_router.currentRoute.params.panoId" readonly)
          van-field.bd-b.bd-t.mgt2(label='房间号(固定分配)' label-width='140px' :value="getUserInfoData.user_id" readonly)

          //- van-field.bd-b.bd-t.mgt2(label='房间号(固定分配)' label-width='140px' :value="getUserInfoData.user_id" readonly)
          //-   van-button(round type="primary" size='small' @click='copyText(getUserInfoData.user_id)' slot='button') 复制

        van-button.w150(type='danger' @click='disconnect' v-if='connected' size='small' icon='cross' round) 退出房间
        van-button.w150(type='info' @click='connect(true)' size='small' v-else icon='plus' round) 创建房间

    van-tab(title="当前房间" v-if="connected && connectInfo.user_id")
      .jc-between.h100p

        .user-list.ff-cn.scroll-y.w150.bd-r
          .user-item.ai-center.jc-start.pdb1(v-for="item in connectInfo.sessions" :key="item.user_id")
            img.w30.mg0.round.flex-auto(:src='item.avatar')
            .pdx1.flex-1.overflow-hidden
              .name.omit {{item.nickname}}
              .bottom-mark
                van-tag(type="danger" v-if="item.ismaster" round) 房主
                van-tag.mgl1(type="success" v-if="item.user_id === connectInfo.user_id" round) 我
        //- 信息列表
        .ff-cn.flex-1
          .flex-1.ai-stretch.overflow-hidden(style='position:relative;')
            .msg-list.ff-cn.scroll-y.flex-1(ref='msgScroll' @scroll='handleScroll')
              .msg-item.ai-start.flex-auto(v-for="item in msgList" :key="item.id" :class='{self: !item.from}')
                img.w30.mg0.round.flex-auto(:src='item.avatar')
                .pdx1.msg-wrap.ff-cn
                  .name.omit {{item.nickname}}
                    van-tag(type="danger" v-if="item.ismaster" round) 房主
                  .msg-content {{item.content}}

            .new-msg-tip(@click='scrollToNewMsg' v-show="hasNewMsg") 有新消息来啦~

          .msg-box.bd-t.ai-stretch.border-radius
            van-field(placeholder='输入要发送的消息' v-model="content" @keydown.prevent.enter.native="sendChat"
              rows="2" autosize type="textarea" maxlength="200" style='padding:10px;')
            .msg-opts.ff-cn.jc-around.pd1.flex-auto
              .limit(:class='{danger: content.length === 200}') {{content.length}}
                span.fc-b2 /200
              .ai-center.mgt1.jc-end
                van-button.mgr1(type="info" size='small' :disabled='!content.length' @click='sendChat') 发送消息
                van-button(:type="isStartVoice ? 'danger' : 'primary'" size='small' icon-prefix='' icon=' el-icon-microphone' v-if="ismaster" @click='isStartVoice ? stopVoice() : startVoice()') {{isStartVoice ? '结束语音' : '开始语音'}}
                van-button(:type="isStartVoice ? 'danger' : 'primary'" size='small' icon-prefix='' icon=' el-icon-microphone' v-else-if='!ismaster && client' @click='isStartVoice ? stopVoiceMasses() : startVoiceMasses()') {{isStartVoice ? '静音' : '取消静音'}}

    van-tab(title="加入房间" v-else)
      van-field.bd-b.bd-t.mgt2(label='房间号' v-model="connectId"  placeholder='请输入房间号')
        van-button(round type="primary" size='small' icon='plus' slot='button' @click='connect(false)') 加入房间

</template>

<script>
import { mapGetters } from 'vuex'
import { pauseAllAudio, replaySceneOrBgMusic } from '@/utils/audio'
import { isPc, copyText } from '@/utils'
import 'ws-audio-api'
const { WSAudioAPI } = window
// 62924
export default {
  name: 'ScreenSync',
  components: {
    Dialog: _ => import('../base/dialog/'),
  },
  computed: {
    ...mapGetters([
      'userInfo',
    ]),
    // 用户信息
    getUserInfoData () {
      if (this.userInfo) {
        return this.userInfo
      }
      return false
    },
    getUserObj () {
      let obj = {}
      this.connectInfo.sessions.map(it => {
        obj[it.user_id] = it
      })
      return obj
    },
  },
  data () {
    this.isPc = isPc()
    this.copyText = copyText
    this.TYPES = {
      ErrorMessage: -1,
      Connected: 1,
      ChatMessage: 2,
      JoinRoom: 11,
      LeaveRoom: 12,
      CloseRoom: 13,
      SceneRotate: 21,
      SceneSwitch: 22,
      StartVoice: 31,
      StopVoice: 32,
    }
    return {
      baseURL: $globalconfig.URLS.WS_BASE_URL,
      show: false,
      // {"room_id":87749,"user_id":14809,"nickname":"博文","avatar":"http:/32","sessions":[{"user_id":14809,"nickname":"博文","avatar":"http2","ismaster":true}]}}
      connectInfo: { room_id: '', sessions: [], user_id: '', nickname: '', avatar: '' },
      connected: false,
      content: '', // 消息框内容
      msgList: [],
      active: 0,
      connectId: '',
      isStartVoice: false,
      ismaster: false,
      hasNewMsg: false,
      client: null,
      // 是否语音
      isVoiceCall: false,
      isZhichiVoice: true,
      localStream: null,
    }
  },
  watch: {
    msgList (val) {
      let el = this.$refs.msgScroll
      if (!el) return
      let scrollLength = el.scrollHeight - el.offsetHeight
      if (scrollLength - el.scrollTop >= 100) {
        this.hasNewMsg = true
      } else {
        this.hasNewMsg = false
        this.$nextTick(() => {
          setTimeout(() => {
            el.scrollTop = el.scrollHeight
          }, 200)
        })
      }
    },
    // show (val) {
    //   if (!val) {
    //     $VM.$krp.autoRotate()
    //     replaySceneOrBgMusic()
    //     // $VM.$krp.controlsAllVideoin(true)
    //   }
    // },
  },
  created () {
    this.connectInfoCopy = JSON.stringify(this.connectInfo)
    if(this.$_router.currentRoute.query.room_id) {
      this.connectId = this.$_router.currentRoute.query.room_id
      this.active = 1
      this.connect (false)
    }
  },
  methods: {
    shareRoom (user_id) {
      let that = this
      var ua = window.navigator.userAgent.toLowerCase();
      console.log(ua.match(/MicroMessenger/i) == 'micromessenger')
      wx.miniProgram.getEnv(function (res) {
        console.log(res)
      })
      if (ua.match(/MicroMessenger/i) == 'micromessenger') {   //判断是否是微信环境
        //微信环境
        wx.miniProgram.getEnv(function (res) {
          if (res.miniprogram) {
            // 小程序环境下逻辑
            //小程序发送信息```
            var info = {
              user_id: user_id, //参数一
              pano_id: that.$_router.currentRoute.params.panoId, //参数二
            };
            // this.$vgo.tip('创建房间成功，请点击右上角转发房间', 'warning')
            alert('创建房间成功，请点击右上角转发房间')
            wx.miniProgram.postMessage({
              data: info
            });

          } else {
            // window.location.href = 'https://www.baidu.com';
            //非小程序环境下逻辑

          }
        })
      } else {
        //非微信环境逻辑
        // window.location.href = '';
      }
    },
    // 游客接收语音
    startVoiceMasses() {
      if (this.localStream) {
        console.log('取消静音')
        console.log(this.localStream)
        this.isStartVoice = true
        this.localStream.unmuteAudio()
      }
    },
    // 游客关闭语音
    stopVoiceMasses() {
      if (this.localStream) {
        console.log('静音')
        console.log(this.localStream)
        this.isStartVoice = false
        this.localStream.muteAudio()
      }
    },
    async joinTRTC() {
      try {
        if (!this.isZhichiVoice) {
          console.log('您的设备不支持语音，请升级系统或微信版本')
          return this.$vgo.tip('您的设备不支持语音，请升级系统或微信版本', 'warning')
        }
        TRTC.checkSystemRequirements().then((checkResult) => {
          if (!checkResult.result) {
            console.log(checkResult, 'checkResult')
            // SDK 不支持当前浏览器，根据用户设备类型建议用户使用 SDK 支持的浏览器
            this.client = null
            this.isZhichiVoice = false
            this.$vgo.tip('SDK不支持当前浏览器，请升级系统版本或微信版本', 'warning')
          }
        });
        //创建客户端
        this.client = TRTC.createClient({
          mode: 'rtc',
          sdkAppId: this.connectInfo.appsdkid,
          userId: this.connectInfo.user_id + '',
          userSig: this.connectInfo.usersig
        });
        this.client.on('stream-added', event => {
          const remoteStream = event.stream;
          // this.$vgo.tip("订阅远端流: " + remoteStream.getId(), 'success')
          //订阅远端流
          this.client.subscribe(remoteStream);
        });
        this.client.on('stream-subscribed', event => {
          const remoteStream = event.stream;
          console.log(remoteStream, 7)
          // this.$vgo.tip("远端流订阅成功: " + remoteStream.getId(), 'success')
          var div = document.createElement("div")
          div.setAttribute("id", remoteStream.getId())
          document.querySelector("#app").appendChild(div)
          remoteStream.play(remoteStream.getId());
        });
        //加入房间
        await this.client.join({ roomId: parseInt(this.connectInfo.room_id) });
        console.log('进入语音房间成功8')
        this.$vgo.tip('进入语音房间成功', 'success')
        //创建本地流
        const mics = await TRTC.getMicrophones()
        if (mics && mics.length === 0) {
          this.client = null
          return this.$vgo.tip('没有麦克风设备', 'warning')
        }
        console.info(mics, 6)
        const localStream = TRTC.createStream({
          userId: this.connectInfo.user_id, audio: true, video: false, microphoneId: mics[0].deviceId, mirror: true
        });
        //初始化音频流
        await localStream.initialize()
        console.log('初始化音频流成功9')
        this.$vgo.tip('初始化音频流成功', 'success')
        // html的id='local_stream'
        localStream.play('local_stream')
        localStream.on('error', error => {
          console.log(error, 6)
          const errorCode = error.getCode();
          if (errorCode === 0x4043) {
            // PLAY_NOT_ALLOWED,引导用户手势操作并调用 stream.resume 恢复音视频播放
            this.$vgo.open(() => {
              localStream.resume()
            }, '自动播放被浏览器阻止，您确定要重新播放吗？')
          }
        });
        //发布本地音频流
        this.client.publish(localStream)
        this.localStream = localStream
        // 游客，处理状态isStartVoice
        if (!this.ismaster) {
          this.startVoiceMasses()
        }
      } catch (err) {
        console.log(err, 4)
        this.$vgo.tip("进入语音房间失败", 'warning')
      }
    },
    scrollToNewMsg () {
      let el = this.$refs.msgScroll
      this.hasNewMsg = false
      el.scrollTop = el.scrollHeight
    },
    handleScroll () {
      let el = this.$refs.msgScroll
      let scrollLength = el.scrollHeight - el.offsetHeight
      if (scrollLength - el.scrollTop <= 100) this.hasNewMsg = false
    },
    open () {
      this.show = true

      $VM.$krp.autoRotate()
      pauseAllAudio()
      $VM.$krp.controlsAllVideoin(false)
    },
    connect (ismaster) {
      this.ismaster = ismaster
      let baseURL = ''
      if (this.baseURL.substr(this.baseURL.length - 1, 1) === '/') {
        baseURL = this.baseURL
      } else {
        baseURL = this.baseURL + '/'
      }
      let url = baseURL + `panorama?token=${this.$AUTH.getToken(true)}&panoid=${this.$_router.currentRoute.params.panoId}`
      if (!ismaster && !this.connectId) {
        this.$vgo.tip('请输入房间号!', 'warning')
        return
      }
      url += ismaster ? '&ismaster=true' : '&roomid=' + this.connectId
      this.$vgo.openLoading()
      this.socket = new WebSocket(url)
      if (this.ismaster) {
        console.log(111)
        this.socket.binaryType = 'arraybuffer'
        this.shareRoom (this.userInfo.user_id)
      } 
      this.eventHandler()
    },
    panoSync () {
      if (!this.ismaster) return
      this.$vgo.on('socket:scene', id => {
        if (!this.connected) return
        this.send(this.TYPES.SceneSwitch, { scene_id: id })
      })
      this.$vgo.on('socket:rotate', id => {
        if (!this.connected) return
        this.$krp.switchAutoRotate(0)
        this.send(this.TYPES.SceneRotate, { ...this.$krp.getView(), scene_id: this.$krp.getSceneId() })
      })
      document.querySelector('#pano').addEventListener('wheel', () => {
        if (!this.connected) return
        this.$krp.switchAutoRotate(0)
        this.send(this.TYPES.SceneRotate, { ...this.$krp.getView(), scene_id: this.$krp.getSceneId() })
      })
    },
    eventHandler () {
      this.socket.onopen = e => {
        this.$vgo.closeLoading()
        this.connected = true
      }
      this.socket.onclose = e => {
        this.$vgo.closeLoading()
         // 关闭语音
        this.stopVoice()
        this.connected = false
        this.content = '' // 消息框内容
        this.msgList = []
        this.active = 0
        this.connectId = ''
        this.isStartVoice = false
        this.ismaster = false
        this.hasNewMsg = false
        this.client = null
        this.localStream = null
        // 是否语音
        this.isVoiceCall = false
        this.isZhichiVoice = true
        this.connectInfo = JSON.parse(this.connectInfoCopy)
      }
      this.socket.onerror = e => {
        this.$vgo.closeLoading()
        this.$vgo.tip('连接出错!', 'warning')
      }
      this.socket.onmessage = this.onmessage
    },
    disconnect () {
      this.$vgo.open(() => {
        // this.socket.close()
        this.$vgo.openLoading()
        if (!this.ismaster) {
          // 游客
          this.send(this.TYPES.LeaveRoom)
          this.socket.close()
          // 关闭语音
          this.stopVoice()
          this.connected = false
          this.content = '' // 消息框内容
          this.msgList = []
          this.active = 0
          this.connectId = ''
          this.isStartVoice = false
          this.ismaster = false
          this.hasNewMsg = false
          this.client = null
          this.localStream = null
          // 是否语音
          this.isVoiceCall = false
          this.isZhichiVoice = true
          this.connectInfo = JSON.parse(this.connectInfoCopy)
        } else {
          // 房主
          this.socket.close()
        }
      }, '您确定要退出当前房间吗?')
    },
    send (type, data) {
      if (this.connected) {
        data = JSON.stringify({
          type: type,
          data: JSON.stringify(data || {}),
        })
        this.socket.send(data)
      }
    },
    // 房主开启语音
    startVoice () {
      console.log(this.connectInfo, 1)
      if (this.connectInfo.sessions.length <= 1) {
        this.$vgo.tip('当前房间没有其他用户!', 'warning')
        return
      }
      if (!this.isStartVoice) {
        if (this.connectInfo && this.connectInfo.appsdkid) {
          this.joinTRTC()
        } else {
          this.streamer = new WSAudioAPI.Streamer({}, this.socket)
          this.streamer.start(err => {
            console.log(err, 2)
            this.$vgo.tip('找不到请求设备', 'warning')
            this.isStartVoice = false
            if (this.ismaster) {
              this.send(this.TYPES.StopVoice)
            }
          })
        }
        this.isStartVoice = true
        this.send(this.TYPES.StartVoice)
      } else {
        this.$vgo.tip('语音已开启!', 'success')
      }
    },
    // 房主结束语音
    stopVoice () {
      if (this.isStartVoice) {
        console.log(this.connectInfo, 11)
        if (this.connectInfo && this.connectInfo.appsdkid) {
          if (this.client) {
            try {
              if (this.localStream) {
                this.client.unpublish(this.localStream)
              }
              this.client.leave()
              console.log("语音退出成功")
            } catch (err) {
              console.log(err, 3)
              console.log("语音退出失败")
            }
          }
        } else {
          console.log('stop2,未获取到appsdkid')
          this.streamer && this.streamer.stop()
          this.streamer = null
        }
        this.isStartVoice = false
        this.send(this.TYPES.StopVoice)
      }
    },
    // 发送聊天信息
    sendChat () {
      if (this.content) {
        this.send(this.TYPES.ChatMessage, {
          content: this.content,
        })
        this.msgList.push({
          content: this.content,
          user_id: this.connectInfo.user_id,
          avatar: this.connectInfo.avatar,
          ismaster: this.ismaster,
          nickname: this.connectInfo.nickname
        })
        this.content = ''
      }
    },
    onmessage (e) {
      if (typeof e.data === 'string') {
        const message = JSON.parse(e.data)
        if (!message) return
        const data = message.data
        // 错误消息
        if (message.type === this.TYPES.ErrorMessage) {
          this.$vgo.tip(data.error, 'warning')
          // 连接服务器成功
        } else if (message.type === this.TYPES.Connected) {
          this.connectInfo = Object.assign({}, this.connectInfo, data)
          this.panoSync()
          // 聊天消息
        } else if (message.type === this.TYPES.ChatMessage) {
          Object.assign(data, this.getUserObj[data.from])
          this.msgList.push(data)
          // 进入房间
        } else if (message.type === this.TYPES.JoinRoom) {
          this.connectInfo.sessions.splice(0, this.connectInfo.sessions.length, ...data.sessions)
          // 离开房间
        } else if (message.type === this.TYPES.LeaveRoom) {
          this.connectInfo.sessions.splice(0, this.connectInfo.sessions.length, ...data.sessions)
          // 解散房间
        } else if (message.type === this.TYPES.CloseRoom) {
          this.$vgo.tip('互动结束!', 'warning')
          this.socket.close()
          this.connected = false
          // 场景转动
        } else if (message.type === this.TYPES.SceneRotate) {
          // {scene_id: 168981, hlookat: 5.726439221000599, vlookat: 0} "rotate"
          this.$krp._krpano.call(`lookto(${data.hlookat},${data.vlookat},${data.fov},tween(easeInOutQuad,0.5))`)
          if (this.$krp.getSceneId() != data.scene_id) {
            this.$vgo.emit('sync:scene', data.scene_id)
          }
          // 切换场景
        } else if (message.type === this.TYPES.SceneSwitch) {
          this.$vgo.emit('sync:scene', data.scene_id)
          // 开始语音消息
        } else if (message.type === this.TYPES.StartVoice) {
          this.$vgo.open(() => {
            this.isStartVoice = true
            if (this.connectInfo && this.connectInfo.appsdkid) {
              console.log('新语音模式----')
              this.joinTRTC()
            } else {
              console.log('旧语音模式----')
              this.player = new WSAudioAPI.Player({}, this.socket)
              this.player.start()
            }
          }, "接收到语音消息是否接听？")
          //结束语音消息
        } else if (message.type == this.TYPES.StopVoice) {
          console.log(this.connectInfo, 12)
          if (this.connectInfo && this.connectInfo.appsdkid) {
            if (this.client) {
              try {
                if (this.localStream) {
                  this.client.unpublish(this.localStream)
                }
                this.client.leave()
                console.log("语音退出成功")
              } catch (err) {
                console.log(err, 312)
                console.log("语音退出失败")
              }
            }
          } else {
            console.log('stop1,未获取到appsdkid')
            this.player && this.player.stop()
          }
          this.$vgo.tip('语音链接结束!', 'warning')
        }
      }
    },
  },
}
</script>
<style lang="stylus">
@media only screen and (max-width: 700px)
  .screen-sync
    .user-list
      width 100px!important
    .bottom-mark
      .van-tag
        margin-top 5px
    .msg-box
      flex-flow column
      .msg-opts
        text-align right
.screen-sync
  // .van-tabs__wrap
  .van-tabs
    overflow hidden
  .van-tabs__content
    flex 1
    .van-tab__pane
      height 100%
      padding 12px
  .new-msg-tip
    position absolute
    bottom 10px
    left 50%
    transform translateX(-50%)
    background-color #9c0
    padding 6px
    border-radius 20px
    cursor pointer
    color #fff
    box-shadow 0 0 10px rgba(#000, 0.3)
  .msg-list
    padding 0 10px
    scroll-behavior smooth
    .msg-item
      width 80%
      padding 10px 0
      &.self
        margin-left auto
        flex-flow row-reverse
        .msg-wrap
          align-items flex-end
      .msg-wrap
        align-items flex-start
        .msg-content 
          margin-top 5px
          background-color skyblue
          color #fff
          padding 5px
          border-radius 5px
          line-height 16px
      // .name.omit
      //   van-tag
      // .msg-content
</style>